package ubi.quando.UI;

import java.util.HashMap;
import java.util.Map;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.SimpleLocationOverlay;
import org.osmdroid.views.util.constants.MapViewConstants;

import ubi.quando.App.Contact;
import ubi.quando.App.EventBase;
import ubi.quando.App.EventMeeting;
import ubi.quando.App.EventPickUp;
import ubi.quando.App.EventType;
import ubi.quando.App.GeoToAddress;
import ubi.quando.App.PickUpParticipant;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class ChooseLocationActivity extends Activity implements
		MapViewConstants {

	private UbiApplication mApp;

	private MapViewUbi mMapView;
	private MapController mMapController;
	private EditText mAddress;
	private Button mConfirm;
	private TextView mTvAddress;

	private SimpleLocationOverlay mDestOverlay;
	private SimpleLocationOverlay mLocOverlay;

	private ScaleBarOverlay mScaleBarOverlay;

	private EventBase mEvent;
	private EventType mType;

	private PickUpParticipant mParticipant;
	private Map<Contact, PickUpParticipant> mAdded;
	private Map<Contact, PickUpParticipant> mRemoved;

	private boolean mIsChoosigDest;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.osmdroid_dialog);

		mApp = (UbiApplication) getApplication();
		mApp.setCurrentActivity(this);

		mMapView = (MapViewUbi) findViewById(R.id.mapview);
		mAddress = (EditText) findViewById(R.id.txt_address);
		mConfirm = (Button) findViewById(R.id.btn_confirm);
		mTvAddress = (TextView) findViewById(R.id.tv_address);

		mMapView.setTileSource(TileSourceFactory.MAPNIK);
		mMapView.setBuiltInZoomControls(true);
		mMapView.setMultiTouchControls(true);

		mMapController = this.mMapView.getController();
		mMapController.setZoom(12);
		mMapController.setCenter(new GeoPoint(UbiApplication.DEFAULT_LAT,
				UbiApplication.DEFAULT_LONG));

		mDestOverlay = new SimpleLocationOverlay(this);
		mLocOverlay = new SimpleLocationOverlay(this);

		mScaleBarOverlay = new ScaleBarOverlay(this);
		mMapView.getOverlays().add(mScaleBarOverlay);

		mAddress.setOnKeyListener(new AddressKeyListener());
		mConfirm.setOnClickListener(new ConfirmClickListener());
		mMapView.setOnLongClickListener(new MapLongClickListener());

		initFont();
	}

	private void initFont() {
		Typeface font = Typeface.createFromAsset(getAssets(), "AGENCYR.TTF");

		mAddress.setTypeface(font);
		mConfirm.setTypeface(font);
		mTvAddress.setTypeface(font);
	}

	@Override
	protected void onResume() {
		super.onResume();
		mApp.setCurrentActivity(this);

		Bundle b = getIntent().getExtras();
		if (b != null) {
			EventType type = EventType.FromInt(b
					.getInt(EventType.SerializeName));
			mIsChoosigDest = b
					.getBoolean(ArrangeEventBaseActivity.SerializeIsDest);
			switch (type) {
			case MEETING:
				OnResumeMeeting(b);
				break;
			case I_PICK_U:
				OnResumeIPU(b);
				break;
			case PICK_ME_UP:
				OnResumePMU(b);
				break;
			}

		}
	}

	private void OnResumePMU(Bundle b) {
		mType = EventType.PICK_ME_UP;
		mEvent = (EventPickUp) b.getSerializable(EventBase.SerializeName);
		AddDestinationOverlay();
		AddLocationOverlay();
	}

	@SuppressWarnings("unchecked")
	private void OnResumeIPU(Bundle b) {
		mType = EventType.I_PICK_U;
		mIsChoosigDest = b.getBoolean(ArrangeEventBaseActivity.SerializeIsDest);
		mEvent = (EventPickUp) b.getSerializable(EventBase.SerializeName);

		if (mIsChoosigDest != true) {
			if (b.getBoolean(AddParticipantsPickUpActivity.SerializePPU)) {
				mParticipant = (PickUpParticipant) b
						.getSerializable(PickUpParticipant.SerializeName);
				mAdded = (Map<Contact, PickUpParticipant>) b
						.getSerializable(AddParticipantsPickUpActivity.SerializeAdded);
				mRemoved = (Map<Contact, PickUpParticipant>) b
						.getSerializable(AddParticipantsPickUpActivity.SerializeRemoved);
			}
			AddLocationOverlay();
		} else {
			AddDestinationOverlay();
		}
	}

	private void OnResumeMeeting(Bundle b) {
		mType = EventType.MEETING;
		mEvent = (EventMeeting) b.getSerializable(EventBase.SerializeName);
		AddDestinationOverlay();
	}

	private void AddDestinationOverlay() {
		GeoPoint dest = mEvent.GetDestination();
		if (dest != null) {
			mDestOverlay.setLocation(dest);
			mMapView.getOverlays().add(mDestOverlay);
			mMapView.invalidate();
		}
	}

	private void AddLocationOverlay() {
		GeoPoint loc = null;
		if (mType == EventType.PICK_ME_UP) {
			loc = ((EventPickUp) mEvent).GetPickUpLocation();

		} else if (mType == EventType.I_PICK_U) {
			loc = mParticipant.getLocation();
		}

		if (loc != null) {
			mLocOverlay.setLocation(loc);
			mMapView.getOverlays().add(mLocOverlay);
			mMapView.invalidate();
		}
	}

	private void SetLocation(GeoPoint loc) {
		// adding marker to map
		if (mType == EventType.PICK_ME_UP) {
			if (loc == null) {
				((EventPickUp) mEvent).SetPickUpLocation(mMapView.GetLoc());
			} else {
				((EventPickUp) mEvent).SetPickUpLocation(loc);
			}
			mLocOverlay.setLocation(((EventPickUp) mEvent).GetPickUpLocation());
		} else if (mType == EventType.I_PICK_U) {
			if (loc == null) {
				mParticipant.setLocation(mMapView.GetLoc());
			} else {
				mParticipant.setLocation(loc);
			}
			mLocOverlay.setLocation(mParticipant.getLocation());
		}

		mMapView.getOverlays().add(mLocOverlay);
		mMapView.invalidate();
	}

	private void SetLocationName() {
		if (mType == EventType.PICK_ME_UP) {
			((EventPickUp) mEvent).setmPULName(GeoToAddress
					.getAddress(((EventPickUp) mEvent).GetPickUpLocation()));
		} else if (mType == EventType.I_PICK_U) {
			mParticipant.setLocName(GeoToAddress.getAddress(mParticipant
					.getLocation()));
		}

	}

	private void SetDestination(GeoPoint loc) {
		if (loc == null) {
			mEvent.SetDestination(mMapView.GetLoc());
		} else {
			mEvent.SetDestination(loc);
		}

		mDestOverlay.setLocation(mEvent.GetDestination());
		mMapView.getOverlays().add(mDestOverlay);
		mMapView.invalidate();
	}

	private void SetDestinationName() {
		mEvent.setDestName(GeoToAddress.getAddress(mEvent.GetDestination()));
	}

	private void ReturnFromMap() {
		Intent intent = null;
		Bundle b = new Bundle();
		b.putSerializable(EventBase.SerializeName, mEvent);

		switch (mType) {
		case MEETING:
			intent = new Intent(mMapView.getContext(),
					ArrangeMeetingActivity.class);
			intent.putExtras(b);
			startActivity(intent);
			break;
		case I_PICK_U:
			if (mIsChoosigDest) {
				intent = new Intent(mMapView.getContext(),
						ArrangeIPickUActivity.class);
				intent.putExtras(b);
				startActivity(intent);
			} else {
				b.putBoolean(AddParticipantsPickUpActivity.SerializePPU, true);
				b.putSerializable(PickUpParticipant.SerializeName, mParticipant);
				b.putSerializable(AddParticipantsPickUpActivity.SerializeAdded,
						(HashMap<Contact, PickUpParticipant>) mAdded);
				b.putSerializable(
						AddParticipantsPickUpActivity.SerializeRemoved,
						(HashMap<Contact, PickUpParticipant>) mRemoved);
				intent = new Intent(mMapView.getContext(),
						AddParticipantsPickUpActivity.class);
				intent.putExtras(b);
				startActivity(intent);
			}
			break;
		case PICK_ME_UP:
			intent = new Intent(mMapView.getContext(),
					ArrangePickMeUpActivity.class);
			intent.putExtras(b);
			startActivity(intent);
			break;
		}
	}

	public class AddressKeyListener implements OnKeyListener {

		public boolean onKey(View v, int keyCode, KeyEvent event) {
			if (keyCode == KeyEvent.KEYCODE_ENTER) {
				GeoPoint point = GeoToAddress.getGeo(mAddress.getText()
						.toString());
				mMapController.setCenter(point);

				if (mType == EventType.MEETING || mIsChoosigDest == true) {
					SetDestination(point);
				} else {
					SetLocation(point);
				}

			}
			return true;
		}
	}

	public class ConfirmClickListener implements OnClickListener {

		public void onClick(View v) {
			if (mType == EventType.MEETING || mIsChoosigDest == true) {
				SetDestinationName();
			} else {
				SetLocationName();
			}
			ReturnFromMap();
		}
	}

	public class MapLongClickListener implements OnLongClickListener {
		public boolean onLongClick(View view) {
			if (mType == EventType.MEETING || mIsChoosigDest == true) {
				SetDestination(null);
			} else {
				SetLocation(null);
			}
			return true;
		}
	}
}
